package com.boot.down.service.impl;

import com.boot.down.entity.UserRedPaper;
import com.boot.down.service.RedisRedPaperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@Service
public class RedisRedPaperServiceImpl implements RedisRedPaperService {

    private static final String PREFIX = "red_paper_list_";
    /**
     * 每次去除1000条。 避免取出太多消耗内存
     */
    private static final int TIME_SIZE = 1000;


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DataSource dataSource = null;

    @Override
    //开启新线程运行(异步操作)
    @Async
    public void saveUserRedPaperByRedis(Long redPaperId, BigDecimal amount) {

        System.err.println("开始保存数据");
        Long start = System.currentTimeMillis();
        //获取列表操作对象
        BoundListOperations ops = redisTemplate.boundListOps(PREFIX + redPaperId);
        Long size = ops.size();
        Long times = size % TIME_SIZE == 0 ? size / TIME_SIZE : size / TIME_SIZE + 1;
        int count = 0;
        List<UserRedPaper> userRedPaperList = new ArrayList<>(TIME_SIZE);
        for(int i = 0; i < times; i++){
            List userIdList = null;
            if(i == 0){
                userIdList = ops.range(i * TIME_SIZE, (i + 1) * TIME_SIZE);
            }else{
                userIdList = ops.range(i * TIME_SIZE + 1, (i + 1) * TIME_SIZE);
            }
            userRedPaperList.clear();
            //保存红包信息
            for(int j = 0; j < userIdList.size(); j++){
                String args = userIdList.get(j).toString();
                String[] arr = args.split("-");
                String userIdStr = arr[0];
                String timeStr = arr[1];
                Long userId = Long.parseLong(userIdStr);
                Long time = Long.parseLong(timeStr);
                //生成抢红包信息
                UserRedPaper userRedPaper = new UserRedPaper();
                userRedPaper.setRedId(redPaperId);
                userRedPaper.setUserId(userId);
                userRedPaper.setAmount(amount);
                userRedPaper.setCreateTime(new Timestamp(time));
                userRedPaper.setRemark("抢红包 " + redPaperId);
                userRedPaperList.add(userRedPaper);

            }
            //插入红包信息
            count += executeBatch(userRedPaperList);
        }
        //删除redis列表
        redisTemplate.delete(PREFIX+ redPaperId);
        Long end = System.currentTimeMillis();
        System.out.println("保存数据库结束， 用时为：" + (end - start) + "毫秒，共 " + count + "条数据被保存");

    }

    /**
     * 使用jdbc批量处理redis缓存数据
     * @param userRedPaperList
     * @return
     */
    private int executeBatch(List<UserRedPaper> userRedPaperList){

        Connection connection = null;
        Statement statement = null;
        int []count = null;

        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);
            statement = connection.createStatement();
            if(userRedPaperList.size() > 0){
                for(UserRedPaper userRedPaper : userRedPaperList){
                    String sql1 = "update red_paper set sm_sup_count = sm_sup_count - 1 where id = "+ userRedPaper.getRedId();
                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String sql2 = " insert into user_red_paper(red_id, user_id, amount, create_time, remark)" +
                            " values ("+userRedPaper.getRedId()+", "+userRedPaper.getUserId()+", " +
                            userRedPaper.getAmount() +", "+
                            "'"+df.format(userRedPaper.getCreateTime())+"', " +
                            "'"+userRedPaper.getRemark()+"')";
                    statement.addBatch(sql1);
                    statement.addBatch(sql2);
                }
                //批量执行
                count = statement.executeBatch();
                //提交事物
                connection.commit();

            }

        } catch (SQLException e) {
            throw new RuntimeException("抢红包程序执行错误");
        } finally {
            //关闭数据源
            try {
                if(connection != null && !connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        //返回插入红包行数
        return count.length/2;
    }
}
